package com.example.demo.controller;

import com.example.demo.domain.User;
import com.example.demo.entity.ChatMessage;
import com.example.demo.entity.Messages;
import com.example.demo.service.MessagesService;
import com.example.demo.service.UserService;
import com.example.demo.utils.TokenUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.util.Date;
import java.util.Map;
import java.util.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

@Controller
@RequiredArgsConstructor
@Slf4j
public class WebSocketChatController {

    private final SimpMessagingTemplate messagingTemplate;
    private final MessagesService messagesService;
    private final UserService userService;

    /**
     * 处理发送消息请求
     * @param chatMessage 聊天消息
     * @param token 认证token
     */
    @MessageMapping("/chat.sendMessage")
    public void sendMessage(@Payload ChatMessage chatMessage, @Header("token") String token) {
        log.info("收到WebSocket消息: {}", chatMessage);
        
        try {
            // 验证token并获取用户信息
            Map<String, String> tokenMap = TokenUtil.parseToken(token);
            User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserName, tokenMap.get("userName")));
            
            if (user == null) {
                log.error("无效的token或用户不存在");
                return;
            }
            
            // 设置发送者ID
            chatMessage.setSenderId(Long.valueOf(user.getId()));
            chatMessage.setSenderName(user.getUserName());
            
            // 生成消息ID和时间戳
            if (chatMessage.getMessageId() == null) {
                chatMessage.setMessageId(UUID.randomUUID().toString().replace("-", ""));
            }
            chatMessage.setTimestamp(System.currentTimeMillis());
            
            // 保存消息到数据库
            if (chatMessage.getType() == ChatMessage.MessageType.CHAT) {
                Messages message = new Messages();
                message.setMessageId(chatMessage.getMessageId());
                message.setContent(chatMessage.getContent());
                message.setSenderId(chatMessage.getSenderId());
                message.setReceiverId(chatMessage.getReceiverId());
                message.setIsGroup(chatMessage.getIsGroup());
                message.setStatus(1); // 已发送
                message.setDeleteFlag(0); // 未删除
                message.setCreateTime(new Date());
                message.setUpdateTime(new Date());
                message.setForwardCount(0);
                
                messagesService.save(message);
            }
            
            // 发送消息到接收者
            if (chatMessage.getIsGroup()) {
                // 群聊消息发送到topic
                messagingTemplate.convertAndSend("/topic/group." + chatMessage.getReceiverId(), chatMessage);
            } else {
                // 私聊消息发送到用户队列
                messagingTemplate.convertAndSendToUser(
                    chatMessage.getReceiverId().toString(),
                    "/queue/messages",
                    chatMessage
                );
                
                // 同时发送给发送者（用于多端同步）
                messagingTemplate.convertAndSendToUser(
                    chatMessage.getSenderId().toString(),
                    "/queue/messages",
                    chatMessage
                );
            }
            
            log.info("消息发送成功: {}", chatMessage.getMessageId());
            
        } catch (Exception e) {
            log.error("处理WebSocket消息时出错", e);
        }
    }
    
    /**
     * 处理已读回执
     * @param chatMessage 包含已读信息的消息
     * @param token 认证token
     */
    @MessageMapping("/chat.markRead")
    public void markRead(@Payload ChatMessage chatMessage, @Header("token") String token) {
        try {
            // 验证token并获取用户信息
            Map<String, String> tokenMap = TokenUtil.parseToken(token);
            User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserName, tokenMap.get("userName")));
            
            if (user == null) {
                log.error("无效的token或用户不存在");
                return;
            }
            
            // 标记消息为已读
            messagesService.markMessagesAsRead(token, chatMessage.getSenderId().toString());
            
            // 发送已读回执给发送者
            chatMessage.setType(ChatMessage.MessageType.READ);
            chatMessage.setReceiverId(chatMessage.getSenderId()); // 接收者变为原发送者
            chatMessage.setSenderId(Long.valueOf(user.getId())); // 发送者变为当前用户
            
            messagingTemplate.convertAndSendToUser(
                chatMessage.getReceiverId().toString(),
                "/queue/read-receipts",
                chatMessage
            );
            
            log.info("已读回执发送成功: 用户 {} 已读来自 {} 的消息", user.getId(), chatMessage.getReceiverId());
            
        } catch (Exception e) {
            log.error("处理已读回执时出错", e);
        }
    }
    
    /**
     * 处理用户加入连接
     * @param chatMessage 加入消息
     * @param headerAccessor 消息头访问器
     */
    @MessageMapping("/chat.addUser")
    public void addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor, @Header("token") String token) {
        try {
            // 验证token并获取用户信息
            Map<String, String> tokenMap = TokenUtil.parseToken(token);
            User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserName, tokenMap.get("userName")));
            
            if (user == null) {
                log.error("无效的token或用户不存在");
                return;
            }
            
            // 将用户信息存储在WebSocket会话中
            headerAccessor.getSessionAttributes().put("userId", user.getId());
            headerAccessor.getSessionAttributes().put("username", user.getUserName());
            
            log.info("用户加入WebSocket: {}", user.getUserName());
            
            // 发送用户在线状态更新
            chatMessage.setType(ChatMessage.MessageType.JOIN);
            chatMessage.setSenderId(Long.valueOf(user.getId()));
            chatMessage.setSenderName(user.getUserName());
            
            // 广播用户上线消息（可选）
            // messagingTemplate.convertAndSend("/topic/public", chatMessage);
            
        } catch (Exception e) {
            log.error("处理用户加入时出错", e);
        }
    }
}